﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data;
using System.Data.SqlClient;

namespace BEELab.Svc
{
    /// <summary>
    /// Summary description for BeeSvc
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class BeeSvc : System.Web.Services.WebService
    {

        [WebMethod(EnableSession = true)]
        public void SetVisibility(int ID, bool isVisible)
        {
            BEELab.Logic.ProgramManagement.StageManagement.BlockElements.SetVisibility(ID, isVisible);
        }

        // Delete Block Element
        [WebMethod(EnableSession = true)]
        public void DeleteElement(int ID)
        {
            int place = BEELab.Logic.ProgramManagement.StageManagement.BlockElements.GetPlace(ID);

            if (place != -1)
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.DeleteElement(ID);
        }

        private void UpdateElement(int ID, int ParentID, int Place)
        {
            SqlCommand command = new SqlCommand();
            command.CommandText = "UPDATE BlockElements SET ParentID=@ParentID, Place=@Place WHERE ID=@ID";
            command.Parameters.Add(new SqlParameter("@ParentID", ParentID));
            command.Parameters.Add(new SqlParameter("@Place", Place));
            command.Parameters.Add(new SqlParameter("@ID", ID));
            BEELab.Data.DBHelper.ExecuteNonQuery(command);
        }

        // assigns order number to each element in the container & saves the logic layer into db
        [WebMethod(EnableSession = true)]
        public void SubmitLogic(string list)
        {
            string IDList = "";
            list.Split('&').ToList().ForEach(d =>
            {
                var ar = d.Split('=');
                int id = int.Parse(ar[0].Replace("list[", "").Replace("]", ""));
                if (!IDList.Equals(""))
                {
                    IDList += ", ";
                }
                IDList += id;
            });

            SqlCommand command = new SqlCommand();
            command.CommandText = "SELECT ID, ParentID, Place, Type FROM BlockElements WHERE ID IN (" + IDList + ")";
            command.Parameters.Add(new SqlParameter("@List", IDList));
            DataTable dt = BEELab.Data.DBHelper.ExecuteQuery(command);

            if (dt == null)
                return;

            Dictionary<int, int> counters = new Dictionary<int, int>();

            int ParentID, Place;

            list.Split('&').ToList().ForEach(d =>
            {
                var ar = d.Split('=');
                int id = int.Parse(ar[0].Replace("list[", "").Replace("]", ""));

                //BEELab.Logic.ProgramManagement.StageManagement.BlockElements.BlockElement cc = new Logic.ProgramManagement.StageManagement.BlockElements.BlockElement(id);
                DataRow cc = (dt.Select("ID=" + id))[0];
                ParentID = int.Parse(cc["ParentID"].ToString());
                Place = int.Parse(cc["Place"].ToString());

                if (cc != null)
                {
                    if (ar[1].Equals("null"))
                    {
                        cc["ParentID"] = 0;

                        if (counters.ContainsKey(int.Parse(cc["ParentID"].ToString())))
                        {
                            counters[int.Parse(cc["ParentID"].ToString())]++;
                            cc["Place"] = counters[int.Parse(cc["ParentID"].ToString())];
                        }
                        else
                        {
                            counters[int.Parse(cc["ParentID"].ToString())] = 1;
                            cc["Place"] = 1;
                        }

                        if (cc["Type"].ToString().Equals("Block") == false)
                            cc["Place"] = 0;

                        if (ParentID != int.Parse(cc["ParentID"].ToString()) || Place != int.Parse(cc["Place"].ToString()))
                        {
                            UpdateElement(id, int.Parse(cc["ParentID"].ToString()), int.Parse(cc["Place"].ToString()));
                        }
                    }

                    else
                    {
                        cc["ParentID"] = int.Parse(ar[1]);

                        if (counters.ContainsKey(int.Parse(cc["ParentID"].ToString())))
                        {
                            counters[int.Parse(cc["ParentID"].ToString())]++;
                            cc["Place"] = counters[int.Parse(cc["ParentID"].ToString())];
                        }
                        else
                        {
                            counters[int.Parse(cc["ParentID"].ToString())] = 1;
                            cc["Place"] = 1;
                        }

                        if (ParentID != int.Parse(cc["ParentID"].ToString()) || Place != int.Parse(cc["Place"].ToString()))
                        {
                            UpdateElement(id, int.Parse(cc["ParentID"].ToString()), int.Parse(cc["Place"].ToString()));
                        }
                    }
                }
            });
        }

        // adds a new block to db
        [WebMethod(EnableSession = true)]
        public void AddOrUpdateBlock(int StageID, string Name, string Description, int ID, Boolean isVisible)
        {
            if (ID != 0)
            {
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.BlockElement block = new Logic.ProgramManagement.StageManagement.BlockElements.BlockElement(ID);
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.UpdateElement(ID, block.ParentID, block.Place, Name, Description, block.Content);
            }
            else
            {
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.CreateElement("Block", StageID, 0, 0, Name, Description, "", isVisible);
            }
        }

        // adds a new code to db
        [WebMethod(EnableSession = true)]
        public void AddOrUpdateCode(int StageID, string Name, string Description, string Content, int ID, Boolean isVisible)
        {
            if (ID != 0)
            {
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.BlockElement code = new Logic.ProgramManagement.StageManagement.BlockElements.BlockElement(ID);
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.UpdateElement(ID, code.ParentID, code.Place, Name, Description, code.Content);
            }
            else
            {
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.CreateElement("Code", StageID, 0, 0, Name, Description, Content, isVisible);
            }
        }

        // adds a new call to db
        [WebMethod(EnableSession = true)]
        public void AddOrUpdateCall(int StageID, string Name, string Description, string Content, int ID, Boolean isVisible)
        {
            if (ID != 0)
            {
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.BlockElement call = new Logic.ProgramManagement.StageManagement.BlockElements.BlockElement(ID);
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.UpdateElement(ID, call.ParentID, call.Place, Name, Description, call.Content);
            }
            else
            {
                BEELab.Logic.ProgramManagement.StageManagement.BlockElements.CreateElement("Call", StageID, 0, 0, Name, Description, Content, isVisible);
            }
        }

        // update method for name,description,content of block/code/call [used for inplace editing]
        [WebMethod(EnableSession = true)]
        public void UpdateData(string Name, string Description, string Content, int ID, char updateType)
        {
            BEELab.Logic.ProgramManagement.StageManagement.BlockElements.BlockElement element = new BEELab.Logic.ProgramManagement.StageManagement.BlockElements.BlockElement(ID);

            if (updateType != 'e')
            {
                Content = element.Content;
            }
            if (updateType != 'n')
            {
                Name = element.Name;
            }
            if (updateType != 'd')
            {
                Description = element.Description;
            }
            

            BEELab.Logic.ProgramManagement.StageManagement.BlockElements.UpdateElement(ID, element.ParentID, element.Place, Name, Description, Content);
        }

    }
}
